<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <style>
      /* 填写样式 */
    </style>
  </head>

  <body>
    <!-- 填写标签 -->
    <script type="text/javascript">
      /**
       * 首先说明一下为什么操作的是returnObj但返回的是oNamespace,
       * 因为我们的returnObj是用于对oNamespace某个属性的地址的引用
       * 我对这个题的写法可以分为三个阶段，
       * 第一阶段，正常判断，如果当前访问的属性不是对象也就是说到头了，
       * 手动将其换成空对象{}
       * 第二阶段，借助assign函数，如若returnObj[element]不为对象则返回值会是前面的{}，这波特性卡的太six了
       * 当然得注意的是憋写反了，应该是{}写在前面当默认值
       * 第三阶段，根据=运算符特性，将其连接起来提高理解难度，漂亮！
       */
      function namespace(oNamespace, sPackage) {
        let returnObj = oNamespace;
        sPackage.split(".").forEach((element) => {
          // 第一阶段
          // typeof returnObj[element] != "object"
          // ? (returnObj[element] = {})
          // : (returnObj = returnObj[element]);

          // 第二阶段
          //returnObj[element] = Object.assign({}, returnObj[element]);
          //returnObj = returnObj[element];

          // 第三阶段
          returnObj = returnObj[element] = Object.assign(
            {},
            returnObj[element]
          );
        });
        return oNamespace;
      }
      console.log(namespace({ a: { test: 1, b: 2 } }, "a.b.c.d"));
    </script>
  </body>
</html>
